﻿namespace Pub.Class
{
    using System;
    using System.Collections.Generic;
    using System.Threading;

    public class ThreadPoolEx
    {
        private readonly object _lockObject = new object();
        private int _nextTask;
        private List<ThreadStart> _tasks;

        public void Execute(int maxThreads, List<ThreadStart> tasks)
        {
            if (!tasks.IsNull() && (tasks.Count != 0))
            {
                this._tasks = tasks;
                if (tasks.Count < maxThreads)
                {
                    maxThreads = tasks.Count;
                }
                ManualResetEvent[] waitHandles = new ManualResetEvent[maxThreads];
                for (int i = 0; i < maxThreads; i++)
                {
                    waitHandles[i] = new ManualResetEvent(false);
                    new Thread(new ParameterizedThreadStart(this.WorkerThreadProc)).Start(waitHandles[i]);
                }
                WaitHandle.WaitAll(waitHandles);
            }
        }

        private void WorkerThreadProc(object threadParameter)
        {
            ManualResetEvent event2 = (ManualResetEvent) threadParameter;
            while (true)
            {
                ThreadStart start;
                lock (this._lockObject)
                {
                    if (this._nextTask >= this._tasks.Count)
                    {
                        break;
                    }
                    start = this._tasks[this._nextTask];
                    this._nextTask++;
                }
                start();
            }
            event2.Set();
        }
    }
}

